# -*- coding: utf-8 -*-
"""
邮件推送模块
负责通过邮件发送告警消息
"""

import smtplib
import time
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header
from typing import Dict, Any, List, Optional
from common.logger import get_logger
from common.config import config

logger = get_logger(__name__)


class EmailPusher:
    """邮件推送器"""
    
    def __init__(self):
        """初始化邮件推送器"""
        self.smtp_server = config.get('email.smtp_server', '')
        self.smtp_port = config.get('email.smtp_port', 587)
        self.username = config.get('email.username', '')
        self.password = config.get('email.password', '')
        self.from_email = config.get('email.from_email', '')
        self.from_name = config.get('email.from_name', '日志分析系统')
        
        if not all([self.smtp_server, self.username, self.password, self.from_email]):
            logger.warning("邮件配置不完整")
    
    def send_email(self, to_emails: List[str], subject: str, content: str, 
                  content_type: str = 'html') -> bool:
        """
        发送邮件
        
        Args:
            to_emails: 收件人邮箱列表
            subject: 邮件主题
            content: 邮件内容
            content_type: 内容类型 (html/plain)
            
        Returns:
            是否发送成功
        """
        if not all([self.smtp_server, self.username, self.password, self.from_email]):
            logger.error("邮件配置不完整")
            return False
        
        try:
            # 创建邮件对象
            msg = MIMEMultipart()
            msg['From'] = f"{self.from_name} <{self.from_email}>"
            msg['To'] = ', '.join(to_emails)
            msg['Subject'] = Header(subject, 'utf-8')
            
            # 添加邮件内容
            if content_type == 'html':
                msg.attach(MIMEText(content, 'html', 'utf-8'))
            else:
                msg.attach(MIMEText(content, 'plain', 'utf-8'))
            
            # 连接SMTP服务器
            server = smtplib.SMTP(self.smtp_server, self.smtp_port)
            server.starttls()  # 启用TLS加密
            server.login(self.username, self.password)
            
            # 发送邮件
            server.send_message(msg)
            server.quit()
            
            logger.info(f"邮件发送成功: {subject} -> {to_emails}")
            return True
            
        except Exception as e:
            logger.error(f"邮件发送失败: {e}")
            return False
    
    def send_alarm_email(self, alarm_data: Dict[str, Any], to_emails: List[str]) -> bool:
        """
        发送告警邮件
        
        Args:
            alarm_data: 告警数据
            to_emails: 收件人邮箱列表
            
        Returns:
            是否发送成功
        """
        try:
            # 构建邮件内容
            subject = self._build_email_subject(alarm_data)
            html_content = self._build_email_html_content(alarm_data)
            plain_content = self._build_email_plain_content(alarm_data)
            
            # 发送HTML邮件
            return self.send_email(to_emails, subject, html_content, 'html')
            
        except Exception as e:
            logger.error(f"发送告警邮件失败: {e}")
            return False
    
    def _build_email_subject(self, alarm_data: Dict[str, Any]) -> str:
        """
        构建邮件主题
        
        Args:
            alarm_data: 告警数据
            
        Returns:
            邮件主题
        """
        try:
            log_data = alarm_data.get('log_data', {})
            strategy = alarm_data.get('strategy', {})
            
            app_name = log_data.get('app_name', '未知应用')
            level = log_data.get('level', '未知级别')
            strategy_name = strategy.get('name', '未知策略')
            
            return f"[日志告警] {app_name} - {level} - {strategy_name}"
            
        except Exception as e:
            logger.error(f"构建邮件主题失败: {e}")
            return "[日志告警] 系统告警通知"
    
    def _build_email_html_content(self, alarm_data: Dict[str, Any]) -> str:
        """
        构建HTML邮件内容
        
        Args:
            alarm_data: 告警数据
            
        Returns:
            HTML内容
        """
        try:
            log_data = alarm_data.get('log_data', {})
            strategy = alarm_data.get('strategy', {})
            
            html_content = f"""
            <!DOCTYPE html>
            <html>
            <head>
                <meta charset="utf-8">
                <style>
                    body {{ font-family: Arial, sans-serif; margin: 20px; }}
                    .header {{ background-color: #ff4444; color: white; padding: 15px; border-radius: 5px; }}
                    .section {{ margin: 20px 0; padding: 15px; border: 1px solid #ddd; border-radius: 5px; }}
                    .label {{ font-weight: bold; color: #333; }}
                    .value {{ color: #666; }}
                    .log-content {{ background-color: #f5f5f5; padding: 10px; border-radius: 3px; font-family: monospace; }}
                    .footer {{ margin-top: 30px; padding-top: 15px; border-top: 1px solid #ddd; color: #999; font-size: 12px; }}
                </style>
            </head>
            <body>
                <div class="header">
                    <h2>🚨 日志告警通知</h2>
                </div>
                
                <div class="section">
                    <h3>策略信息</h3>
                    <p><span class="label">策略名称:</span> <span class="value">{strategy.get('name', '未知')}</span></p>
                    <p><span class="label">策略描述:</span> <span class="value">{strategy.get('description', '无')}</span></p>
                </div>
                
                <div class="section">
                    <h3>日志信息</h3>
                    <p><span class="label">应用名称:</span> <span class="value">{log_data.get('app_name', '未知')}</span></p>
                    <p><span class="label">日志级别:</span> <span class="value">{log_data.get('level', '未知')}</span></p>
                    <p><span class="label">主机:</span> <span class="value">{log_data.get('host', '未知')}</span></p>
                    <p><span class="label">时间:</span> <span class="value">{log_data.get('timestamp', '未知')}</span></p>
                </div>
                
                <div class="section">
                    <h3>日志内容</h3>
                    <div class="log-content">{log_data.get('message', '无内容')}</div>
                </div>
                
                <div class="section">
                    <h3>告警时间</h3>
                    <p>{time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}</p>
                </div>
                
                <div class="footer">
                    <p>此消息由日志分析系统自动发送</p>
                    <p>请及时处理相关告警信息</p>
                </div>
            </body>
            </html>
            """
            
            return html_content
            
        except Exception as e:
            logger.error(f"构建HTML邮件内容失败: {e}")
            return f"<p>告警邮件内容构建失败: {str(e)}</p>"
    
    def _build_email_plain_content(self, alarm_data: Dict[str, Any]) -> str:
        """
        构建纯文本邮件内容
        
        Args:
            alarm_data: 告警数据
            
        Returns:
            纯文本内容
        """
        try:
            log_data = alarm_data.get('log_data', {})
            strategy = alarm_data.get('strategy', {})
            
            content = f"""日志告警通知

策略信息:
- 策略名称: {strategy.get('name', '未知')}
- 策略描述: {strategy.get('description', '无')}

日志信息:
- 应用名称: {log_data.get('app_name', '未知')}
- 日志级别: {log_data.get('level', '未知')}
- 主机: {log_data.get('host', '未知')}
- 时间: {log_data.get('timestamp', '未知')}

日志内容:
{log_data.get('message', '无内容')}

告警时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}

---
此消息由日志分析系统自动发送
请及时处理相关告警信息"""
            
            return content
            
        except Exception as e:
            logger.error(f"构建纯文本邮件内容失败: {e}")
            return f"告警邮件内容构建失败: {str(e)}"
    
    def send_batch_alarm_emails(self, alarm_list: List[Dict[str, Any]], 
                               to_emails: List[str]) -> Dict[str, int]:
        """
        批量发送告警邮件
        
        Args:
            alarm_list: 告警列表
            to_emails: 收件人邮箱列表
            
        Returns:
            发送结果统计
        """
        success_count = 0
        failed_count = 0
        
        for alarm_data in alarm_list:
            try:
                if self.send_alarm_email(alarm_data, to_emails):
                    success_count += 1
                else:
                    failed_count += 1
                
                # 添加延迟避免发送过快
                time.sleep(1)
                
            except Exception as e:
                logger.error(f"批量发送告警邮件失败: {e}")
                failed_count += 1
        
        result = {
            'success_count': success_count,
            'failed_count': failed_count,
            'total_count': len(alarm_list)
        }
        
        logger.info(f"批量发送告警邮件完成: {result}")
        return result
    
    def test_connection(self) -> bool:
        """
        测试邮件连接
        
        Returns:
            连接是否正常
        """
        if not all([self.smtp_server, self.username, self.password]):
            return False
        
        try:
            server = smtplib.SMTP(self.smtp_server, self.smtp_port)
            server.starttls()
            server.login(self.username, self.password)
            server.quit()
            return True
            
        except Exception as e:
            logger.error(f"邮件连接测试失败: {e}")
            return False
    
    def send_test_email(self, to_email: str) -> bool:
        """
        发送测试邮件
        
        Args:
            to_email: 收件人邮箱
            
        Returns:
            是否发送成功
        """
        try:
            subject = "日志分析系统 - 邮件推送测试"
            content = f"""
            <h2>邮件推送测试</h2>
            <p>这是一封测试邮件，用于验证邮件推送功能是否正常工作。</p>
            <p>发送时间: {time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())}</p>
            <p>如果您收到这封邮件，说明邮件推送功能配置正确。</p>
            """
            
            return self.send_email([to_email], subject, content, 'html')
            
        except Exception as e:
            logger.error(f"发送测试邮件失败: {e}")
            return False
    
    def get_config_info(self) -> Dict[str, Any]:
        """
        获取配置信息
        
        Returns:
            配置信息
        """
        return {
            'smtp_server': self.smtp_server,
            'smtp_port': self.smtp_port,
            'username': self.username,
            'from_email': self.from_email,
            'from_name': self.from_name,
            'connection_status': self.test_connection()
        } 